Computer programs are lists of instructions that describe actions to be performed by a computer or processor-based device. When a computer program is loaded and executed on computer hardware, the computer will behave in a predetermined manner by following the instructions of the computer program. Accordingly, the computer becomes a specialized machine that performs the tasks prescribed by the instructions. A programmer using a programming language creates the instructions comprising a computer program. As computer programs became more sophisticated, programming languages have evolved from low-level machine code languages, easily understood by computers, to high-level source code languages more readily comprehensible to humans. Such programs include a plurality of constructs including subroutines.
A subroutine (e.g., function, method, procedure . . . ) is a portion of relatively independent code within a larger program designed to perform a particular task. Subroutines are beneficial at least because they modularize or break code up into logical segments. This affords many advantages such as reducing program redundancy, enabling reuse across programs, decomposing complex problems into smaller pieces and improving readability, among other things. Subroutines themselves are composed of a body of code for execution, parameters that are passed when called and a return result. While subroutines are common programming constructs, a generalization thereof, namely co-routines are not.
In contrast to subroutines, co-routines are program components that allow multiple entry points as well as suspending and resuming execution at particular code locations. The start of subroutine is the only entry point, while the start of a co-routine is only one entry point. Subsequent points can follow returns. Further, a subroutine only returns once, while co-routines can return multiple times. Further yet, co-routine lifespan is defined by utilization and subroutine lifespan is completed after a sequential execution.
While co-routines are more generic, they are also less widely employed due at least in part to implementation problems/complexities. Most implementations are confined to low-level assembly language implementations. In high-level languages programmers are responsible for maintaining state and execution paths via global state variables, flags and the like. Among other things, this is difficult to comprehend and maintain and can also be computationally expensive as it adds an additional layer of interpretation.